package htmlbrowser;

import htmlbrowser.domtree.HTMLDOMTreeNode;

import java.util.LinkedList;
import java.util.NoSuchElementException;

import javax.swing.text.BadLocationException;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.swing.tree.DefaultMutableTreeNode;

public class HTMLBrowserDocument extends HTMLDocument {
	private LinkedList<DefaultMutableTreeNode> treeNodes;
	
	HTMLBrowserDocument(StyleSheet styles) {
		super(styles);
	}

	public HTMLEditorKit.ParserCallback getReader(int pos) {
		return new HTMLBrowserReader(pos);
	}

	class HTMLBrowserReader extends HTMLDocument.HTMLReader {
		public HTMLBrowserReader(int pos) {
			super(pos);
			treeNodes = new LinkedList<DefaultMutableTreeNode>();
		}
		
		public void flush() throws BadLocationException {
			super.flush();
		}
		
		public void handleComment(char[] data, int pos) {
			super.handleComment(data, pos);
		}

		public void handleEndOfLineString(String eol) {
			/*for (int i = 0; i < treeNodes.size(); i++)
				System.out.print("\t");
			System.out.println("EndOfLine");
			*/
			super.handleEndOfLineString(eol);
		}
		
		public void handleEndTag(HTML.Tag t, int pos) {
			/*for (int i = 0; i < treeNodes.size(); i++)
				System.out.print("\t");
			System.out.println("EndTag: " + t.toString() + " (" + pos + ")");
			*/
			try {
				if (t != HTML.Tag.HTML)
					if (((HTMLDOMTreeNode) treeNodes.getFirst().getUserObject()).tag == t)
						treeNodes.pop();
			} catch (NoSuchElementException e) {
				System.err.println(e);
			}
			
			super.handleEndTag(t, pos);
		}

		public void handleError(String errorMsg, int pos) {
			super.handleError(errorMsg, pos);
		}

		public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
			/*for (int i = 0; i < treeNodes.size(); i++)
				System.out.print("\t");
			System.out.println("SimpleTag: " + t.toString()
					+ " (pos: " + pos + "; attr: " + a.getAttributeCount() + ")");
			*/
			DefaultMutableTreeNode node =
				new DefaultMutableTreeNode(
						new HTMLDOMTreeNode(t, a));
			treeNodes.peekFirst().add(node);
			
			super.handleSimpleTag(t, a, pos);
		}

		public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
			/*for (int i = 0; i < treeNodes.size(); i++)
				System.out.print("\t");
			System.out.println("StartTag: " + t.toString()
					+ " (pos: " + pos + "; attr: " + a.getAttributeCount() + ")");
			*/
			DefaultMutableTreeNode node =
				new DefaultMutableTreeNode(
						new HTMLDOMTreeNode(t, a));
			
			if (t != HTML.Tag.HTML)
				treeNodes.peekFirst().add(node);
			else
				Main.frame.domTreeFrame.domTreeModel.setRoot(node);
			
			treeNodes.push(node);
			
			super.handleStartTag(t, a, pos);
		}

		public void handleText(char[] data, int pos) {
			/*for (int i = 0; i < treeNodes.size(); i++)
				System.out.print("\t");
			System.out.println("HandleText: " + new String(data)
					+ " (pos: " + pos + ", length: " + data.length + ")");
			*/
			DefaultMutableTreeNode node =
				new DefaultMutableTreeNode(new String(data));
			treeNodes.peekFirst().add(node);
			
			if (treeNodes.peekFirst().getUserObject() instanceof HTMLDOMTreeNode
					&& ((HTMLDOMTreeNode) treeNodes.peekFirst().getUserObject()).tag
							== HTML.Tag.TITLE)
				Main.frame.setTitle(new String(data) + " - HTML Browser");
			
			super.handleText(data, pos);
		}
	}
	
	static final long serialVersionUID = 0x0001;
}
